use crate::config::init_db;
use crate::dto::client::ClientInfo;
use crate::entity::table::SysUserOnline;
use rbatis::rbdc::DateTime;
use crate::config::DB;
use rbs::to_value;

pub async fn check_user_online(id: String) -> (bool, Option<Vec<SysUserOnline>>) {
    match SysUserOnline::select_by_column(&init_db(), "token_id", id).await {
        Ok(model) => (true, Some(model)),
        Err(_) => (false, None),
    }
}

pub async fn add(req: ClientInfo, u_id: String, token_id: String, token_exp: i64) {
    let id = scru128::new_string();
    let now = DateTime::now();
    let user = super::sys_user::get_by_id(&u_id)
        .await
        .expect("获取用户信息失败");
    let dept = super::sys_dept::get_by_id(&user.user.dept_id).await;
    let sys_user_online = SysUserOnline {
        id,
        u_id,
        token_id,
        token_exp,
        login_time: now,
        user_name: user.user.user_name.clone(),
        dept_name: dept.dept_name.clone(),
        net: req.net.net_work,
        ipaddr: req.net.ip,
        login_location: req.net.location,
        device: req.ua.device,
        browser: req.ua.browser,
        os: req.ua.os,
    };
    let tx = init_db().acquire_begin().await.expect("begin txn error");
    let mut tx = tx.defer_async(|mut tx| async move {
        if tx.done {
            return;
        } else {
            let _ = tx.rollback().await;
            return;
        }
    });
    SysUserOnline::insert(&tx, &sys_user_online)
        .await
        .unwrap();
    let _ = tx.commit().await.expect("commit txn error");
}

pub async fn log_out(token_id: &str) -> hypers::Result<String> {
    match DB.exec("DELETE FROM sys_user_online WHERE token_id = ?", vec![to_value!(token_id)]).await {
        Ok(_) => Ok("成功退出登录".to_owned()),
        Err(_) => Err(hypers::prelude::Error::Other("退出登录失败".to_owned()))
    }
}